#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#define THREAD_NUM       (1000)
#define STACK_SIZE       (2048)
#define DELAY_TICKS_20   (20)
#define DELAY_TICKS_100  (100)

osThreadId_t newThread(char *name, osThreadFunc_t func, char *arg)
{
    osThreadAttr_t attr = {
        name, 0, NULL, 0, NULL, STACK_SIZE, osPriorityNormal, 0, 0
    };
    osThreadId_t tid = osThreadNew(func, (void *)arg, &attr);
    if (tid == NULL) {
        printf("[Thread Test] osThreadNew(%s) failed.\r\n", name);
    } else {
        printf("[Thread Test] osThreadNew(%s) success, thread id: %d.\r\n", name, tid);
    }
    return tid;
}

void threadTest(char *arg)
{
    static int count = 0;
    printf("%s\r\n", arg);
    osThreadId_t tid = osThreadGetId();
    printf("[Thread Test] threadTest osThreadGetId, thread id:%p\r\n", tid);
    while (count < THREAD_NUM) {
        count++;
        printf("[Thread Test] threadTest, count: %d.\r\n", count);
        osDelay(DELAY_TICKS_20);
    }
}

void rtosv2_thread_main(void)
{
    osThreadId_t tid = newThread("test_thread", threadTest, "This is a test thread.");

    const char *t_name = osThreadGetName(tid);
    printf("[Thread Test] osThreadGetName, thread name: %s.\r\n", t_name);

    osThreadState_t state = osThreadGetState(tid);
    printf("[Thread Test] osThreadGetState, state :%d.\r\n", state);

    osStatus_t status = osThreadSetPriority(tid, osPriorityNormal4);
    printf("[Thread Test] osThreadSetPriority, status: %d.\r\n", status);

    osPriority_t pri = osThreadGetPriority(tid);
    printf("[Thread Test] osThreadGetPriority, priority: %d.\r\n", pri);

    status = osThreadSuspend(tid);
    printf("[Thread Test] osThreadSuspend, status: %d.\r\n", status);

    status = osThreadResume(tid);
    printf("[Thread Test] osThreadResume, status: %d.\r\n", status);

    uint32_t stacksize = osThreadGetStackSize(tid);
    printf("[Thread Test] osThreadGetStackSize, stacksize: %u.\r\n", stacksize);

    uint32_t stackspace = osThreadGetStackSpace(tid);
    printf("[Thread Test] osThreadGetStackSpace, stackspace: %u.\r\n", stackspace);

    uint32_t t_count = osThreadGetCount();
    printf("[Thread Test] osThreadGetCount, count: %u.\r\n", t_count);

    osDelay(DELAY_TICKS_100);
    status = osThreadTerminate(tid);
    printf("[Thread Test] osThreadTerminate, status: %d.\r\n", status);
}

static void ThreadTestTask(void)
{
    osThreadAttr_t attr;

    attr.name = "rtosv2_thread_main";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = STACK_SIZE;
    attr.priority = osPriorityNormal;

    printf("\n#####################################################\n");
    printf("//applications/slhsp104_demo: ThreadTestTask\n");

    if (osThreadNew((osThreadFunc_t)rtosv2_thread_main, NULL, &attr) == NULL) {
        printf("[ThreadTestTask] create rtosv2_thread_main: NG\n");
    } else {
        printf("[ThreadTestTask] create rtosv2_thread_main: OK\n");
    }
    printf("#####################################################\n\n");
}
//SYS_RUN(ThreadTestTask);
APP_FEATURE_INIT(ThreadTestTask);
